﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using JiaBao.Core.Infrastructure;

namespace JiaBao.Core.Plugins
{
    /// <summary>
    /// 插件说明文件
    /// </summary>
    public class PluginDescriptor : IComparable<PluginDescriptor>
    {
        #region Ctor
        public PluginDescriptor()
        {
            SupportedVersions = new List<string>();
        }

        public PluginDescriptor(Assembly referencedAssembly, FileInfo originalAssemblyFile, Type pluginType)
            : this()
        {
            ReferencedAssembly = referencedAssembly;
            OriginalAssemblyFile = originalAssemblyFile;
            PluginType = pluginType;
        }
        #endregion

        #region 属性

        /// <summary>
        /// 插件主DLL文件
        /// </summary>
        public virtual string PluginFileName { get; set; }


        /// <summary>
        /// 系统名称
        /// </summary>
        public virtual string SystemName { get; set; }

        /// <summary>
        /// 显示顺序
        /// </summary>
        public virtual int Order { get; set; }

        /// <summary>
        /// 安装与否
        /// </summary>
        public virtual bool Installed { get; set; }

        /// <summary>
        /// 插件支持的框架版本
        /// </summary>
        public virtual IList<string> SupportedVersions { get; set; }


        /// <summary>
        /// 插件入口类
        /// </summary>
        public virtual Type PluginType { get; set; }

        /// <summary>
        /// 插件主DLL程序集
        /// </summary>
        public virtual Assembly ReferencedAssembly { get; internal set; }

        /// <summary>
        /// 插件主DLL原始文件
        /// </summary>
        public virtual FileInfo OriginalAssemblyFile { get; internal set; }

        #region 一般性显示

        /// <summary>
        /// 显示名称
        /// </summary>
        public virtual string FriendlyName { get; set; }

        /// <summary>
        /// 版本号
        /// </summary>
        public virtual string Version { get; set; }

        /// <summary>
        /// 作者
        /// </summary>
        public virtual string Author { get; set; }

        /// <summary>
        /// 说明
        /// </summary>
        public virtual string Descriptor { get; set; }


        #endregion

        #region 未使用


        //public virtual string Group { get; set; }

        //对上游开放
        //对下游开放
        //源文件

        #endregion

        #endregion

        #region 实现接口


        /// <summary>
        /// 排序使用
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(PluginDescriptor other)
        {
            if (Order != other.Order)
                return Order.CompareTo(other.Order);
            return FriendlyName.CompareTo(other.FriendlyName);
        }

        #endregion

        /// <summary>
        /// 尝试获取指定类型的插件实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual T Instance<T>() where T : class, IPlugin
        {
            object instance;
            if (!EngineContext.Current.ContainerManager.TryResolve(PluginType, null, out instance))
            {
                instance = EngineContext.Current.ContainerManager.ResolveUnregistered(PluginType);
            }
            var typedInstance = instance as T;
            if (typedInstance != null)
                typedInstance.PluginDescriptor = this;

            return typedInstance;
        }

        /// <summary>
        /// 获取IPlugin类型的插件
        /// </summary>
        /// <returns></returns>
        public IPlugin Instance()
        {
            return Instance<IPlugin>();
        }

        #region 重写一些方法
       
        public override string ToString()
        {
            return FriendlyName;
        }

        public override int GetHashCode()
        {
            return SystemName.GetHashCode();
        }
        public override bool Equals(object obj)
        {
            var other = obj as PluginDescriptor;
            return other != null &
                SystemName != null &
                SystemName.Equals(other.SystemName);
        }

        #endregion
    }
}
